#ifndef SCENE_H
#define SCENE_H

#include <csugl.h>
#include <entt/entt.hpp>
#include <glog/logging.h>

#include <vector>

struct GameObject;

struct Scene
{
    friend GameObject;

    Scene() : _regi(entt::registry())
    {
        _objects.reserve(64);
    }

    csugl::Ref<GameObject> CreateGameObject();

    template <typename... _CT, typename _Func>
    void ComponentEach(_Func func)
    {
        _regi.view<_CT...>().each(std::move(func));
    }

    template <typename _CT, typename _Compare>
    void SortAs(_Compare func)
    {
        _regi.sort<_CT, _Compare>(std::move(func));
    }

    std::vector<csugl::Ref<GameObject>>::iterator begin() 
    {
        return _objects.begin();
    }

    std::vector<csugl::Ref<GameObject>>::const_iterator begin() const
    {
        return _objects.begin();
    }

    std::vector<csugl::Ref<GameObject>>::iterator end() 
    {
        return _objects.end();
    }

    std::vector<csugl::Ref<GameObject>>::const_iterator end() const
    {
        return _objects.end();
    }

public:
    static csugl::Ref<Scene> Create() 
    {
        return csugl::MakeRef<Scene>();
    }

    inline entt::registry &Regi() { return _regi; }

private:

    entt::registry _regi;
    std::vector<csugl::Ref<GameObject>> _objects;
};


#endif